package com.example.joke.custom.tag

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import java.util.ArrayList

class TagLayout : ViewGroup {

    var mAdapter: BaseAdapter? = null
        set(value) {
            if (value == null) {
                throw Exception("Adapter不能为空")
            }
            field = value
            removeAllViews()
            for (i in 0 until mAdapter!!.getCount()) {
                val view = mAdapter!!.getView(i, this)
                addView(view)
            }
        }
    private val mChildViews: ArrayList<ArrayList<View>> = ArrayList()
    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        Log.d("onMeasure---", "就想打印看一下走了几遍")
        val width = MeasureSpec.getSize(widthMeasureSpec)
        // 高度需要根据子view累加高度计算
        var height = paddingTop + paddingBottom
        // 一行中最高的子view高度
        var maxHeight: Int = 0
        // 一行的宽度
        var totalWidth = paddingLeft + paddingRight
        mChildViews.clear()
        var childViews = ArrayList<View>()
        mChildViews.add(childViews)     // 单行处理
        for (i in 0 until childCount) {
            // for循环测量子view
            val child = getChildAt(i)
            // 优化------》
            if (child.visibility == View.GONE) {
                continue
            }
            // 这段话执行之后就可以获取子view的宽度，因为会调用子view的onMeasure
            measureChild(child, widthMeasureSpec, heightMeasureSpec)

            // margin值，ViewGroup.LayoutParams没有，就用系统的MarginLayoutParams
            // 详细LinearLayout为什么有？可参照
            // LinearLayout有自己的LayoutParams，会重写一个非常重要的方法generateLayoutParams(attrs: AttributeSet?)
            val params: MarginLayoutParams = child.layoutParams as MarginLayoutParams
            maxHeight = Math.max((child.measuredHeight + params.topMargin + params.bottomMargin), maxHeight)
            // 一行不够的情况下，需要换行，暂时未考虑margin

            if ((totalWidth + child.measuredWidth + params.leftMargin + params.rightMargin) < width) { // 无需换行，累加宽度
                totalWidth += (child.measuredWidth + params.leftMargin + params.rightMargin)
//                childViews.add(child)
            } else {    // 换行，累加高度
                height += maxHeight
                // 每次换行后重新计算最大高度，但是要防止最后一行只有一个view的情况，要不然最后一行没有高度
                if (i < childCount -1) {
                    maxHeight = 0
                }
                totalWidth = paddingLeft + paddingRight + child.measuredWidth + params.leftMargin + params.rightMargin
                childViews = ArrayList<View>()
                mChildViews.add(childViews)
//                childViews.add(child)
            }
            childViews.add(child)
        }
        // 单行即代表第一行高度，多行即表示加上最后一行高度
        height += maxHeight
        // 根据子view计算和指定自己的宽高
        setMeasuredDimension(width, height)
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left: Int = paddingLeft
        var top: Int = paddingTop
        var right: Int = 0
        var bottom: Int = 0


        for (mChildView in mChildViews) {
            left = paddingLeft
            // 每一行重新计算最大高度
            var maxHeight = 0
            for (view in mChildView) {
                // 优化------》
                if (view.visibility == View.GONE) {
                    continue
                }
                val params: MarginLayoutParams = view.layoutParams as MarginLayoutParams
                left += params.leftMargin
                val childTop = top + params.topMargin
                right = left + view.measuredWidth
                bottom = childTop + view.measuredHeight
                Log.d("onLayout---for", "left：".plus(left).plus("  top：").plus(childTop).plus("  right：").plus(right).plus("  bottom：").plus(bottom))
                view.layout(left, childTop, right, bottom)
                left = right + params.rightMargin
                maxHeight = Math.max(maxHeight, (view.measuredHeight + params.topMargin + params.bottomMargin))
            }
            top += maxHeight
        }
    }
}